/*
  * ImagesFunctions.c
  *
  *  Created on: 23 nov. 2009
  *      Author: Charly
  */
 #include "OrientationImage.h"
 #include "ToolsFunctions.h"

 double ** kmeans2(int k,int nbelements,int nbIterations,int nbPatch,char* classes){

         double ** resultat = (double**) calloc(k,sizeof(double*));
         int *assoc;
         int i,j,l,lig,parcours,numPatch;
         int nbAffect[k];
         char nomFichier[15];
         int indice;
         int min;
         double distance,distancemini;
         double* unPatch;
         double** uneImage;
         assoc = (int*)calloc(nbelements*nbPatch,sizeof(int));
         FILE* fic;

         for(i=0;i<nbelements*nbPatch;i++)assoc[i]=0;


         //Initialisation des K-means au hasard
         for(i=0;i<k;i++){
                 resultat[i] = (double*)calloc(DIMENSION,sizeof(double));
                 indice = -1;
                 while(indice==-1 || assoc[indice]==1)indice = rand()%(nbelements*nbPatch);
                 assoc[indice]=1;
                 unPatch = (double*)calloc(DIMENSION,sizeof(double));
                 sprintf(nomFichier,"%s_%d.txt",classes,indice/nbPatch);
                 fic = fopen(nomFichier,"r");
                 if(fic==NULL){
                	 printf("probleme\n");
                	 system("pause");
                	 exit(1);
                 }
                 for(l=0;l<(indice%nbPatch)+1;l++){
                	 for(lig=0;lig<DIMENSION;lig++){
                		 fscanf(fic,"%lf|",&unPatch[lig]);
                	 }
                	 fscanf(fic,"\n");
                 }
                 fclose(fic);
                 memcpy(resultat[i],unPatch,DIMENSION*sizeof(double));
                 free(unPatch);
 //              fHogg=fopen("hogg.txt","r");
 //              for(j=0;j<=indice*nbPatch;j++){
 //                      if((j/nbPatch==indice) && (j%nbPatch==0)){
 //                              //tab = (double*)calloc(DIMENSION,sizeof(double));
 //                              for(l=0;l<DIMENSION;l++)fscanf(fHogg,"%lf ",&resultat[j][l]);
 //                              //memcpy(resultat[i],tab,DIMENSION*sizeof(double));
 //                              //free(tab);
 //                      }
 //                      else for(l=0;l<DIMENSION;l++)fscanf(fHogg,"%lf ",&distance);
 //              }
 //              fclose(fHogg);


         }
//         FILE *verif = fopen("verif.txt","a");
//         for(i=0;i<k;i++){
//                 for(j=0;j<DIMENSION;j++){
//                         fprintf(verif,"%lf|",resultat[i][j]);
//                 }
//                 fprintf(verif,"\n");
//         }
//         fclose(verif);



         for(parcours=0;parcours<nbIterations;parcours++){
                 printf("Parcours numero %d\n",parcours);
                 for(i=0;i<NB_KMEANS;i++){
                         nbAffect[i]=0;
                 }
                 //fkmeans = fopen("affectationsKmeans.txt","w");
                 //Parcours des nbelements IOGG
                 //fHogg = fopen("hogg.txt","r");
                 for(i=0;i<nbelements;i++){

                	 sprintf(nomFichier,"%s_%d.txt",classes,i);
                	 fic = fopen(nomFichier,"r");
                	 if(fic==NULL){
                		 printf("probleme\n");
                		 system("pause");
                		 exit(1);
                	 }
                	 uneImage = (double**)calloc(nbPatch,sizeof(double*));
                	 for(l=0;l<nbPatch;l++){
                		 uneImage[l]=(double*)calloc(DIMENSION,sizeof(double));
                		 for(lig=0;lig<DIMENSION;lig++){
                			 fscanf(fic,"%lf|",&uneImage[l][lig]);
                		 }
                		 fscanf(fic,"\n");
                	 }
                	 fclose(fic);

                	 for(numPatch=0;numPatch<nbPatch;numPatch++){
                		 //                              tab = (double*)calloc(DIMENSION,sizeof(double));
                		 //                              for(l=0;l<DIMENSION;l++){
                		 //                                      fscanf(fHogg,"%lf ",&tab[l]);
                		 //                              }
                		 min=0;
                		 distancemini = distanceVect(resultat[0],uneImage[numPatch],DIMENSION);
                		 //distancemini = distanceVect(resultat[0],tab,DIMENSION);
                		 //Recherche du k-means le plus proche
                		 for(j=1;j<k;j++){
                			 distance = distanceVect(resultat[j],uneImage[numPatch],DIMENSION);
                			 //distance = distanceVect(resultat[j],tab,DIMENSION);
                			 if(distance < distancemini){
                				 distancemini = distance;
                				 min = j;
                			 }

                		 }
                		 //assoc[i]=min;
                		 //fprintf(fkmeans,"%d\n",min);
                		 assoc[i*nbPatch + numPatch]=min;
                		 nbAffect[min]++;

                		 //free(tab);
                		 //fprintf(ftest,"element %d k-means %d distance %f\n",i,min,distancemini);
                		 //system("pause");

                		 //Recalcule le nouveau k-means
                		 //                              for(lig=0;lig<DIMENSION;lig++){
                		 //                                      resultat[min][lig]=(resultat[min][lig]+iogg[i][numPatch][lig])/2;
                		 //                              }
                	 }
                	 for(j=0;j<nbPatch;j++){
                		 free(uneImage[j]);
                	 }
                	 free(uneImage);
                 }
 //              fclose(fHogg);
 //              fHogg = fopen("hogg.txt","r");
                 //fclose(fkmeans);
                 for(i=0;i<NB_KMEANS;i++){
                         if(nbAffect[i]!=0){
                                 for(j=0;j<DIMENSION;j++)resultat[i][j]=0;
                         }
                 }
                 for(i=0;i<nbelements*nbPatch;i++){
                	 if(i%nbPatch == 0){
                		 sprintf(nomFichier,"%s_%d.txt",classes,i/nbPatch);
                		 fic = fopen(nomFichier,"r");
                		 if(fic==NULL){
                			 printf("probleme\n");
                			 system("pause");
                			 exit(1);
                		 }
                		 uneImage = (double**)calloc(nbPatch,sizeof(double*));
                		 for(l=0;l<nbPatch;l++){
                			 uneImage[l]=(double*)calloc(DIMENSION,sizeof(double));
                			 for(lig=0;lig<DIMENSION;lig++){
                				 fscanf(fic,"%lf|",&uneImage[l][lig]);
                			 }
                			 fscanf(fic,"\n");
                		 }
                		 fclose(fic);
                	 }
                	 for(j=0;j<DIMENSION;j++){
                		 //fscanf(fHogg,"%lf ",&distance);
                		 //resultat[assoc[i]][j]+=distance;
                		 resultat[assoc[i]][j]+=uneImage[i%nbPatch][j];

                	 }
                	 if(i%nbPatch == nbPatch-1){
                		 for(j=0;j<nbPatch;j++)free(uneImage[j]);
                		 free(uneImage);
                	 }
                 }
                 //fclose(fHogg);

                 for(i=0;i<NB_KMEANS;i++){
                         if(nbAffect[i]!=0){
                                 for(j=0;j<DIMENSION;j++)resultat[i][j]=(double)(resultat[i][j]/(double)nbAffect[i]);
                         }
                 }

 //              for(i=0;i<k;i++){
 //                      nbAffectations = 0;
 //                      //fkmeans = fopen("affectationsKmeans.txt","r");
 //                      fHogg = fopen("hogg.txt","r");
 //                      for(j=0;j<nbPatch*nbelements;j++){
 //                              //fscanf(fkmeans,"%d\n",&min);
 //                              tab = (double*)calloc(DIMENSION,sizeof(double));
 //                              for(l=0;l<DIMENSION;l++){
 //                                      fscanf(fHogg,"%lf ",&tab[l]);
 //                              }
 //                              if(assoc[j]==i){
 //                                      if(nbAffectations==0)for(l=0;l<DIMENSION;l++)resultat[k][l]=0;
 //                                      nbAffectations++;
 //                                      for(l=0;l<DIMENSION;l++){
 //                                              resultat[k][l]+=tab[l];
 //                                      }
 //                              }
 //                              free(tab);
 //                      }
 //                      fclose(fHogg);
 //                      if(nbAffectations >0){
 //                              for(j=0;j<DIMENSION;j++){
 //                                      resultat[k][j]=(double)(resultat[k][j]/(double)nbAffectations);
 //                              }
 //                      }
 //                      //fclose(fkmeans);
 //              }
         }
//         FILE* ftest =fopen("affectKmeans.txt","w");
//
//         for(i=0;i<k;i++){
//                 fprintf(ftest,"%d:%d ",i,nbAffect[i]);
//         }
//         fclose(ftest);

         return resultat;

 }

 double ** kmeans(int k,double *** iogg,int nbelements,int nbIterations,int nbPatch){

          double ** resultat = (double**) calloc(k,sizeof(double*));
          int *assoc;
          int i,j,l,lig,parcours,numPatch;
          int nbAffect[k];
          int indice;
          int min;
          double distance,distancemini;
          assoc = (int*)calloc(nbelements*nbPatch,sizeof(int));

          for(i=0;i<nbelements*nbPatch;i++)assoc[i]=0;


          //Initialisation des K-means au hasard
          for(i=0;i<k;i++){
                  resultat[i] = (double*)calloc(DIMENSION,sizeof(double));
                  indice = -1;
                  while(indice==-1 || assoc[indice]==1)indice = rand()%(nbelements*nbPatch);
                  assoc[indice]=1;
                  memcpy(resultat[i],iogg[indice/nbPatch][indice%nbPatch],DIMENSION*sizeof(double));
  //              fHogg=fopen("hogg.txt","r");
  //              for(j=0;j<=indice*nbPatch;j++){
  //                      if((j/nbPatch==indice) && (j%nbPatch==0)){
  //                              //tab = (double*)calloc(DIMENSION,sizeof(double));
  //                              for(l=0;l<DIMENSION;l++)fscanf(fHogg,"%lf ",&resultat[j][l]);
  //                              //memcpy(resultat[i],tab,DIMENSION*sizeof(double));
  //                              //free(tab);
  //                      }
  //                      else for(l=0;l<DIMENSION;l++)fscanf(fHogg,"%lf ",&distance);
  //              }
  //              fclose(fHogg);


          }
          FILE *verif = fopen("verif.txt","a");
          for(i=0;i<k;i++){
                  for(j=0;j<DIMENSION;j++){
                          fprintf(verif,"%lf|",resultat[i][j]);
                  }
                  fprintf(verif,"\n");
          }
          fclose(verif);



          for(parcours=0;parcours<nbIterations;parcours++){
                  printf("Parcours numero %d\n",parcours);
                  for(i=0;i<NB_KMEANS;i++){
                          nbAffect[i]=0;
                  }
                  //fkmeans = fopen("affectationsKmeans.txt","w");
                  //Parcours des nbelements IOGG
                  //fHogg = fopen("hogg.txt","r");
                  for(i=0;i<nbelements;i++){
                          for(numPatch=0;numPatch<nbPatch;numPatch++){
  //                              tab = (double*)calloc(DIMENSION,sizeof(double));
  //                              for(l=0;l<DIMENSION;l++){
  //                                      fscanf(fHogg,"%lf ",&tab[l]);
  //                              }
                                  min=0;
                                  distancemini = distanceVect(resultat[0],iogg[i][numPatch],DIMENSION);
                                  //distancemini = distanceVect(resultat[0],tab,DIMENSION);
                                  //Recherche du k-means le plus proche
                                  for(j=1;j<k;j++){
                                          distance = distanceVect(resultat[j],iogg[i][numPatch],DIMENSION);
                                          //distance = distanceVect(resultat[j],tab,DIMENSION);
                                          if(distance < distancemini){
                                                  distancemini = distance;
                                                  min = j;
                                          }

                                  }
                                  //assoc[i]=min;
                                  //fprintf(fkmeans,"%d\n",min);
                                  assoc[i*nbPatch + numPatch]=min;
                                  nbAffect[min]++;

                                  //free(tab);
                                  //fprintf(ftest,"element %d k-means %d distance %f\n",i,min,distancemini);
                                  //system("pause");

                                  //Recalcule le nouveau k-means
  //                              for(lig=0;lig<DIMENSION;lig++){
  //                                      resultat[min][lig]=(resultat[min][lig]+iogg[i][numPatch][lig])/2;
  //                              }
                          }
                  }
  //              fclose(fHogg);
  //              fHogg = fopen("hogg.txt","r");
                  //fclose(fkmeans);
                  for(i=0;i<NB_KMEANS;i++){
                          if(nbAffect[i]!=0){
                                  for(j=0;j<DIMENSION;j++)resultat[i][j]=0;
                          }
                  }
                  for(i=0;i<nbelements*nbPatch;i++){
                          for(j=0;j<DIMENSION;j++){
                                  //fscanf(fHogg,"%lf ",&distance);
                                  //resultat[assoc[i]][j]+=distance;
                                  resultat[assoc[i]][j]+=iogg[i/nbPatch][i%nbPatch][j];

                          }
                  }
                  //fclose(fHogg);

                  for(i=0;i<NB_KMEANS;i++){
                          if(nbAffect[i]!=0){
                                  for(j=0;j<DIMENSION;j++)resultat[i][j]=(double)(resultat[i][j]/(double)nbAffect[i]);
                          }
                  }

  //              for(i=0;i<k;i++){
  //                      nbAffectations = 0;
  //                      //fkmeans = fopen("affectationsKmeans.txt","r");
  //                      fHogg = fopen("hogg.txt","r");
  //                      for(j=0;j<nbPatch*nbelements;j++){
  //                              //fscanf(fkmeans,"%d\n",&min);
  //                              tab = (double*)calloc(DIMENSION,sizeof(double));
  //                              for(l=0;l<DIMENSION;l++){
  //                                      fscanf(fHogg,"%lf ",&tab[l]);
  //                              }
  //                              if(assoc[j]==i){
  //                                      if(nbAffectations==0)for(l=0;l<DIMENSION;l++)resultat[k][l]=0;
  //                                      nbAffectations++;
  //                                      for(l=0;l<DIMENSION;l++){
  //                                              resultat[k][l]+=tab[l];
  //                                      }
  //                              }
  //                              free(tab);
  //                      }
  //                      fclose(fHogg);
  //                      if(nbAffectations >0){
  //                              for(j=0;j<DIMENSION;j++){
  //                                      resultat[k][j]=(double)(resultat[k][j]/(double)nbAffectations);
  //                              }
  //                      }
  //                      //fclose(fkmeans);
  //              }
          }
          FILE* ftest =fopen("affectKmeans.txt","w");

          for(i=0;i<k;i++){
                  fprintf(ftest,"%d:%d ",i,nbAffect[i]);
          }
          fclose(ftest);

          return resultat;

  }


 /** Fonction prenant  :
     - un tableau d'images integrales correspondant aux orientations des gradients pour une image donnÃƒÂ©e
     - le centre d'un patch (fenetre dans laquelle on va calculer la somme des normes des orientations des gradients dans chaque sous case)
     - le nombre de pixels de cotÃƒÂ© pour chaque sous case du patch
     *
     Pour chaque sous case du patch (il y en a 16 = 4x4), on calcule la somme des normes pour chaque orientation puis on normalise.
     On retourne un tableau 16x8 contenant
     - 16 lignes (1 par sous case)
     - 8 colonnes (1 par orientation)
 **/
 double ** patch(IplImage ** iog, int xcenter, int ycenter, int nbpixels){

   /*
     0  1  2  3
     4  5  6  7
     8  9 10 11
     12 13 14 15
   */

   // On crÃƒÂ©e un tableau de 16 lignes et 8 colonnes
   int nblign=16, nbcol=8;
   double ** histopatch = (double**)calloc(nblign,sizeof(double*));
   int i;
   for (i = 0 ; i < nblign ; i++){
     histopatch[i] = (double*)calloc(nbcol,sizeof(double));
   }

   // On calcule les coordonnÃƒÂ©es du point haut gauche du patch
   int xtopleft = xcenter - nbpixels - (nbpixels-1);
   int ytopleft = ycenter - nbpixels - (nbpixels-1);
   //printf("topleft x %d y %d \n",xtopleft,ytopleft);
   // coordonnÃƒÂ©es du point haut gauche de la case actuelle
   int xcase = xtopleft;
   int ycase = ytopleft;
   double sumcase = 0; // somme des normes de la case
   double sumcase2;

   // Orientation et numÃƒÂ©ro de case courants
   int orient, nocase;

   // Scalaires dans lesquels seront sockÃƒÂ©s les valeurs des pixels nous intÃƒÂ©ressant
   CvScalar topleft, topright, bottomleft, bottomright;

   // Pour chaque orientation (pour chaque image intÃƒÂ©grale) on parcourt le patch
   for (orient=0 ; orient<8 ; orient++){

     // Pour chaque case on calcule la somme des orientations donnee par
     // somme = pixelenhautagauche + pixelenbasadroite - ( pixelenhautadroite + pixelenbasagauche)
     for (nocase = 0 ; nocase < 16 ; nocase++){

       // On actualise les coordonnÃƒÂ©es de la case
       /*
         0  1  2  3
         4  5  6  7
         8  9 10 11
         12 13 14 15
       */
         if (nocase != 0){
                 if (nocase % 4 == 0){ // numero divisible par 4
                         ycase+=nbpixels;
                         xcase=xtopleft;
                 }
                 else
                 {
                         xcase+=nbpixels;
                 }
         }

       //On rÃƒÂ©cupÃƒÂ¨re les valeurs des quatre coins.

         topleft=cvGet2D(iog[orient], ycase, xcase);
         topright=cvGet2D(iog[orient], ycase, xcase+nbpixels-1);
         bottomleft=cvGet2D(iog[orient], ycase+nbpixels-1, xcase);
         bottomright=cvGet2D(iog[orient], ycase+nbpixels-1, xcase+nbpixels-1);


         // On calcule la somme des normes pour cette case
         sumcase = topleft.val[0] + bottomright.val[0] - ( topright.val[0] + bottomleft.val[0] );

         // on rentre cette somme dans la case de ligne le numero de la case et de colonne l'orientation courante
         histopatch[nocase][orient] = sumcase;


       // On affiche

       //printf("Case %d de (x=%d,y=%d) ÃƒÂ  (x=%d,y=%d)- Orientation %d : norme = %lf\n",nocase,xcase,ycase,xcase+nbpixels-1,ycase+nbpixels-1,orient,sumcase);

     }
     xcase=xtopleft;
     ycase=ytopleft;
   }
   sumcase = 0;
   sumcase2= 0;
   for(i=0;i<8;i++){

           for(nocase=0;nocase<16;nocase++){
                   sumcase+=histopatch[nocase][i];
                   sumcase2+=(double)(histopatch[nocase][i]*histopatch[nocase][i]);
           }

   }
   sumcase = (double)(sumcase/(double)DIMENSION);

   for(i=0;i<8;i++){

           for(nocase=0;nocase<16;nocase++){
                   if(sumcase2 != 0)
                           histopatch[nocase][i] = (double)((double)(histopatch[nocase][i] - sumcase) / (double)pow(sumcase2,0.5));
           }
   }

   return histopatch;

 }

 //Prend un patch et retourne un histogramme (de dimension 1D NB_CASES Ãƒâ€” NB_ORIENT)
 double* patchToHisto(double** patch) {
         double * histogramme = (double*) calloc(DIMENSION, sizeof(double));

         int i;
         for (i = 0; i < NB_CASES; i++) {
                 memcpy(histogramme + i * NB_ORIENT, patch[i], NB_ORIENT*sizeof(double));
         }
         return histogramme;
 }

 //Prend une image (enfin, son chemin...) et retourne un tableau de NB_ORIENT images intÃƒÂ©grales
 IplImage** integralImgOrient(char* filename) { // On choisit l'orientation correspondante

         IplImage *orig8u = cvLoadImage(filename, 0); // grayscale 8bit
         IplImage *orig = cvCreateImage(cvGetSize(orig8u), IPL_DEPTH_32F, 1);
         double ecart;

         cvConvertScale(orig8u, orig, 1.0 / 255.0, 0); // Conversion de l'image originale de 8u vers 32f
 //      if(orig->origin!=IPL_ORIGIN_TL){
 //              IplImage *temp;
 //              cvConvertImage(orig,temp,CV_CVTIMG_FLIP);
 //              orig=cvCloneImage(temp);
 //      }
         IplImage *gradientx = cvCreateImage(cvGetSize(orig), IPL_DEPTH_32F, 1);
         IplImage *gradienty = cvCreateImage(cvGetSize(orig), IPL_DEPTH_32F, 1);

         IplImage ** og = (IplImage **) calloc(NB_ORIENT,sizeof(IplImage *));

         IplImage ** iog = (IplImage **) calloc(NB_ORIENT,sizeof(IplImage *));

         CvScalar gradx, grady, gradnorme;
         int x, y, orient;
         double arg, norme;


         CvSize iiSize;
         iiSize.width = cvGetSize(orig).width + 1;
         iiSize.height = cvGetSize(orig).height + 1;
         for (x = 0; x < NB_ORIENT; x++) {
                 og[x] = cvCreateImage(cvGetSize(orig), IPL_DEPTH_32F, 1);
                 cvSetZero(og[x]);
                 iog[x] = cvCreateImage(iiSize, IPL_DEPTH_64F, 1);
                 cvSetZero(iog[x]);
         }

         cvSobel(orig, gradientx, 1, 0, 3);
         cvSobel(orig, gradienty, 0, 1, 3);

         for (x = 0; x < orig->width; x++) {
                 for (y = 0; y < orig->height; y++) {
                         gradx = cvGet2D(gradientx, y, x);
                         grady = cvGet2D(gradienty, y, x);

                         norme = sqrt(pow(gradx.val[0], 2) + pow(grady.val[0], 2));

                         if(norme!=0)
                                 arg = acos((double)(gradx.val[0] / norme));
                         else arg=M_PI/2;
                         if (grady.val[0] < 0)
                                 arg = (double)(2 * M_PI)-arg;
                         if (gradx.val[0] == 0 && grady.val[0] == 0)
                                 arg = 0;

                         orient = (int) (arg / ((double) (M_PI/4)));

                         orient %=8;
                         ecart = (double)(arg/(double)(M_PI/4)) - orient;

                         gradnorme.val[0] = norme*ecart;

                         cvSet2D(og[orient], y, x, gradnorme);
                         gradnorme.val[0] = norme*(1-ecart);
                         cvSet2D(og[(orient+1)%8], y, x, gradnorme);

                 }
         }

         for (x = 0; x < NB_ORIENT; x++) {
                 //cvNormalize(og[x],og[x],1,0,CV_L2,NULL);
                 cvIntegral(og[x], iog[x], NULL, NULL);

         }
         for(x=0;x<NB_ORIENT;x++){
                 //cvNormalize(iog[x],iog[x],1,0,CV_L2,NULL);
                 cvReleaseImage(&og[x]);
         }
         free(og);
         cvReleaseImage(&gradientx);
         free(gradientx);
         cvReleaseImage(&gradienty);
         free(gradienty);
         cvReleaseImage(&orig);
         cvReleaseImage(&orig8u);
         free(orig);
         free(orig8u);

         return iog;

 }

 int* compareToVisualWords(char* imagePath, double** kmeans, int nbPatches) {

         int* histovisuel = (int*) calloc(NB_KMEANS, sizeof(int));
         IplImage ** iog = integralImgOrient(imagePath);
         int width = cvGetSize(iog[0]).width;
         int height = cvGetSize(iog[0]).height;
         width = width/4;
         height = height/4;
         int iMinWord = 0;
         int i, j;
         double distance = 0;
         double curDistance = 0;
         int *centre;
         int hauteur;
         double* hogg;
         double** patche;
         srand(time(NULL));

         //int randwidth, randheight;

         for (i = 0; i < nbPatches; i++) {

                 hauteur = 19;
                 while(hauteur<20){
                         if(width > height)hauteur = rand()%height;
                         else hauteur = rand()%width;
                 }

                 centre=(int*)calloc(2,sizeof(int));
                 centre[0]=(rand()%(cvGetSize(iog[0]).width-4*hauteur)) + 2*hauteur;
                 centre[1]=(rand()%(cvGetSize(iog[0]).height-4*hauteur)) + 2*hauteur;

                 patche = patch(iog,centre[0],centre[1],hauteur);
                 hogg = patchToHisto(patche);
                 reOrient(hogg);
                 //normalize2(hogg);

                 iMinWord = 0;
                 distance = distanceVect(hogg, kmeans[0], DIMENSION);

                 for (j = 1; j < NB_KMEANS; j++) {
                         curDistance = distanceVect(hogg, kmeans[j], DIMENSION);
                         if (curDistance < distance) {
                                 iMinWord = j;
                                 distance = curDistance;
                         }
                 }

                 histovisuel[iMinWord]++;

                 free(centre);
                 free(hogg);
                 for(j=0;j<16;j++){
                         free(patche[j]);
                 }
                 free(patche);
         }
         /* Free */
         for(i=NB_ORIENT-1;i>=0;i--){
                 cvReleaseImage(&iog[i]);
         }

         free(iog);


         return histovisuel;
 }


 double ** chargerKmeans(char * nomfichier){
         FILE* fp = fopen(nomfichier,"r");
         double ** tab = (double**)calloc(NB_KMEANS,sizeof(double*));
         int i,j;
         for(i=0;i<NB_KMEANS;i++){
                 tab[i]=(double*)calloc(DIMENSION,sizeof(double));
                 for(j=0;j<DIMENSION;j++){
                         fscanf(fp,"%lf|",&tab[i][j]);
                 }
                 fscanf(fp,"\n");
         }
         return tab;
 }

 void reOrient(double * tab){
	 int min=0;
	 int i;
	 double* centre;
	 centre = (double*)calloc(DIMENSION,sizeof(double));
	 for(i=1;i<DIMENSION;i++){
		 if(tab[i]>tab[min])min=i;
	 }

	 for(i=0;i<DIMENSION;i++){
		 centre[i]=tab[(min+i)%DIMENSION];
	 }
	 for(i=0;i<DIMENSION;i++){
		 tab[i]=centre[i];
	 }
	 free(centre);
 }
